package com.tyrone.concurrent.lock;

import com.mysql.cj.LicenseConfiguration;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 重入锁的 公平锁和非公平锁demo
 * 公平锁，按照等待线程的顺序获取锁，也就是说等待时间越长的越先获取锁，效率较低，但是不会出现非公平锁饥饿情况。
 *
 * @author xieyl
 * @create 2021/12/14 22:21
 */
public class FairAndUnfairTest {
    private static Lock fairLock = new ReentrantLock2(true);
    private static Lock unfairLock = new ReentrantLock2(false);

    @Test
    public void fair(){
        testLock(fairLock);
    }

    @Test
    public void unfair(){
        testLock(unfairLock);
    }

    private void testLock(Lock lock){
        for (int i = 0; i < 5; i++) {
            Job job = new Job((ReentrantLock2) lock);
            job.run();
        }
    }

    private static class Job extends Thread {
        private ReentrantLock2 lock;
        public Job(ReentrantLock2 lock){
            this.lock = lock;
        }
        @Override
        public void run(){
            System.out.println("当前线程："+Thread.currentThread().getName()+"  等待队列："+ lock.getQueuedThreads());
            System.out.println("当前线程："+Thread.currentThread().getName()+"  等待队列："+ lock.getQueuedThreads());
        }
    }
    static class ReentrantLock2 extends ReentrantLock{
        public ReentrantLock2(boolean fair){
            super(fair);
        }
        @Override
        public Collection<Thread> getQueuedThreads(){
            List<Thread> arrayList = new ArrayList<Thread>(super.getQueuedThreads());
            Collections.reverse(arrayList);
            return arrayList;
        }
    }
}
